from typing import Dict, Type, Any, List, Optional
from src.core.base_downloader import BaseDownloader
from src.downloaders.xiaohongshu import XiaohongshuDownloader
from src.downloaders.wechat import WechatDownloader
from src.models.download_models import DownloadRequest, BatchDownloadRequest
from src.infrastructure.log_decorators import log_operation
from src.core.progress_manager import ProgressManager
from src.infrastructure.config import config
import uuid
import asyncio
from pathlib import Path
from .file_system_service import FileSystemService
import logging

logger = logging.getLogger(__name__)

class DownloadManager:
    _downloaders: Dict[str, Type[BaseDownloader]] = {
        'xiaohongshu': XiaohongshuDownloader,
        'wechat': WechatDownloader
    }
    
    def __init__(self):
        self.file_system_service = FileSystemService()
        self.progress_manager = ProgressManager()
    
    @classmethod
    @log_operation("download_manager")
    async def get_downloader(cls, platform: str, config_dict: Dict) -> BaseDownloader:
        if platform not in cls._downloaders:
            raise ValueError(f"Unsupported platform: {platform}")
        
        downloader = cls._downloaders[platform](config_dict)
        return downloader
    
    @log_operation("download_manager")
    async def create_task(self, download_request: Dict[str, Any]) -> str:
        """创建下载任务"""
        try:
            task_id = str(uuid.uuid4())
            
            # 获取平台类型和URL
            platform = download_request.get('platform')
            url = download_request.get('url')
            if not platform:
                raise ValueError("Platform is required")
            if not url:
                raise ValueError("URL is required")
                
            # 获取配置
            config_dict = config.config
            
            # 获取下载器实例
            downloader = await self.get_downloader(platform, config_dict)
            
            # 创建下载进度记录
            self.progress_manager.create_task(task_id, 0)  # 初始进度为0
            
            # 异步执行下载任务
            asyncio.create_task(self._execute_download(
                task_id=task_id,
                downloader=downloader,
                url=url
            ))
            
            return task_id
                
        except Exception as e:
            logger.error(f"Failed to create download task: {str(e)}")
            raise ValueError(f"Failed to create download task: {str(e)}")

    async def _execute_download(self, task_id: str, downloader: BaseDownloader, url: str):
        """执行下载任务"""
        try:
            # 执行下载
            result = await downloader.download_by_url(url)
            
            # 更新进度为完成
            self.progress_manager.update_progress(task_id, 100, 'completed')
            
            # 记录下载结果
            logger.info(f"Download completed for task {task_id}: {result.get('title', '')}")
            
        except Exception as e:
            logger.error(f"Download failed for task {task_id}: {str(e)}")
            self.progress_manager.update_progress(task_id, 0, 'failed')
            raise

    @log_operation("download_manager")
    async def create_batch_tasks(self, request: Dict[str, Any]) -> List[str]:
        """创建批量下载任务"""
        # TODO: 实现批量下载逻辑
        raise NotImplementedError("Batch download not implemented yet")

    async def get_file_system_tree(self, path: Optional[str] = None, max_depth: int = 3):
        """获取文件系统树结构"""
        try:
            if not path:
                return {
                    "name": "根目录",
                    "type": "root",
                    "children": [
                        self.file_system_service.scan_directory(root, max_depth)
                        for root in self.file_system_service.root_paths
                    ]
                }
            return self.file_system_service.scan_directory(path, max_depth)
        except Exception as e:
            raise ValueError(f"Failed to get file system tree: {str(e)}")

    async def invalidate_file_system_cache(self, path: Optional[str] = None):
        """清除文件系统缓存"""
        self.file_system_service.invalidate_cache(path)